package com.ruoyi.door.utils.baofu;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson2.JSON;
import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.door.domain.DoorOrder;
import com.ruoyi.door.utils.baofu.entity.PostMasterEntity;
import com.ruoyi.door.utils.baofu.entity.ResultMasterEntity;
import com.ruoyi.door.utils.baofu.entity.RiskInfoEntity;
import com.ruoyi.door.utils.baofu.entity.TerminalInfoEntity;
import com.ruoyi.door.utils.baofu.http.HttpUtil;
import com.ruoyi.door.utils.baofu.rsa.JHSignatureUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class BaoFuJuHeService {
    @Autowired
    private ResourceLoader resourceLoader;
    @Autowired
    private EasyEntityQuery easyEntityQuery;

    public String getResourcePath(String resourcePath) throws IOException {
        Resource resource = resourceLoader.getResource("classpath:" + resourcePath);
        File file = resource.getFile();
        return file.getAbsolutePath();
    }


    public ResultMasterEntity unifiedOrder(String payCode_, String sub_appid_, String sub_openid_, String body_
            , String txnAmt_, String outTradeNo_) {
        try {
            String pfxpath = "D:\\CER_EN_DECODE\\NTestNewKey\\BAOFU20240612_pri.pfx";//商户私钥
            String cerpath = "D:\\CER_EN_DECODE\\NTestNewKey\\BAOFUP20240612_pub.cer";//宝付公钥
            String pfxpwd = BaoFuConstants.PASS_WORD;//私钥密码
            String merId = BaoFuConstants.MEMBER_ID;
            String terId = BaoFuConstants.TERMINAL_ID;
            pfxpath = BaofuUtil.getPath(BaoFuConstants.PFX_PATH);
            cerpath = BaofuUtil.getPath(BaoFuConstants.CER_PATH);
            System.out.println("1111"+pfxpath);
            System.out.println(cerpath);
            String txnAmt = txnAmt_;//用户实际付款金额
            String totalAmt = txnAmt_;//订单总金额

            String txnTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());//报文发送日期时间
            String payCode = payCode_;//"ALIPAY_NATIVE"; //"ALIPAY_NATIVE";//"WECHAT_JSAPI";//QUICK_PASS_NATIVE//QUICK_PASS_APP
            String Method = "unified_order";

            String subMchId = "793936684";//测试传空，生产传SIMID

            ///微信支付参数。
            String sub_appid = sub_appid_;
            String sub_openid = sub_openid_;
            String body = body_;

            ///支付宝参数
            String buyer_id = "";

            //buyer_id，auth_code

            //云闪付APP
            String subMerId = "844330059120001";
            String subMerName = "";
            String subMerAbbr = "";

            String outTradeNo = outTradeNo_;// "OTN" + System.currentTimeMillis();
            log.info("订单号：" + outTradeNo);
            Map<String, Object> Biz_Content = new HashMap<String, Object>();
            Biz_Content.put("agentMerId", "");
            Biz_Content.put("agentTerId", "");
            Biz_Content.put("merId", merId);
            Biz_Content.put("terId", terId);
            Biz_Content.put("outTradeNo", outTradeNo);
            Biz_Content.put("txnAmt", txnAmt);
            Biz_Content.put("txnTime", txnTime);
            Biz_Content.put("totalAmt", totalAmt);
            Biz_Content.put("timeExpire", "120");//订单支付的有效时间，单位：分钟
            Biz_Content.put("prodType", "ORDINARY");//SHARING:分账产品,ORDINARY:普通产品
            Biz_Content.put("payCode", payCode);
            /**
             * WECHAT_JSAPI	微信JSAPI
             * ALIPAY_NATIVE	支付宝扫码支付（主扫）
             * ALIPAY_JSAPI	支付宝生活号支付
             * QUICK_PASS_NATIVE	云闪付主扫
             * QUICK_PASS_NATIVE_JS	云闪付主扫JS
             *
             */
            Map<String, Object> Pay_Extend = new HashMap<String, Object>();
            if (payCode.startsWith("WECHAT")) {
                ///微信支付属性-公共属性

                Pay_Extend.put("name", "");
                Pay_Extend.put("number", "");
                Pay_Extend.put("type", "");
                Pay_Extend.put("body", body);
                Pay_Extend.put("area_info", "");

                ////terminal_info 终端信息参数     支付方式为：WECHAT_MICROPAY该字段必填
                String Deviceid = "";///终端设备号
                TerminalInfoEntity Terminal_Info = new TerminalInfoEntity(payCode, Deviceid);

                ///场景信息	scene_info
//            Map<String,String> Scene_Info = new HashMap<String,String>();
//            Scene_Info.put("id", "");///门店唯一标识
//            Scene_Info.put("name", "");
//            Scene_Info.put("area_code", "");
//            Scene_Info.put("address", "");
//            Pay_Extend.put("scene_info",Scene_Info);

                if (payCode.equals("WECHAT_JSAPI")) {
                    Pay_Extend.put("sub_appid", sub_appid);
                    Pay_Extend.put("sub_openid", sub_openid);
                } else if (payCode.equals("WECHAT_MICROPAY")) {
                    Pay_Extend.put("terminal_info", Terminal_Info);
                }

            } else if (payCode.startsWith("ALIPAY")) {
                Pay_Extend.put("subject", "商品名称");
                Pay_Extend.put("area_info", "");

                ////terminal_info 终端信息参数     支付方式为：ALIPAY_MICROPAY该字段必填
                String Deviceid = "";///终端设备号
                TerminalInfoEntity Terminal_Info = new TerminalInfoEntity(payCode, Deviceid);


                Pay_Extend.put("store_id", "");
                Pay_Extend.put("hb_fq_num", "");
                Pay_Extend.put("hb_fq_seller_percent", "");
                Pay_Extend.put("enable_pay_channels", "");
                Pay_Extend.put("disable_pay_channels", "");

                if (payCode.equals("ALIPAY_JSAPI")) {
                    Pay_Extend.put("buyer_id", buyer_id);
                } else if (payCode.equals("ALIPAY_MICROPAY")) {
                    Pay_Extend.put("terminal_info", Terminal_Info);
                }
            } else if (payCode.startsWith("QUICK_PASS_NATIVE")) {
                Pay_Extend.put("areaInfo", "290001");
            } else if (payCode.startsWith("QUICK_PASS_APP")) {
                Pay_Extend.put("subMerId", subMerId);
                Pay_Extend.put("subMerName", subMerName);
                Pay_Extend.put("subMerAbbr", subMerAbbr);

                Map<String, String> reserved = new HashMap<String, String>();
                reserved.put("ebankEnAbbr", "CQP");
                reserved.put("ebankType", "01");
                Pay_Extend.put("reserved", reserved);
            }

            Biz_Content.put("payExtend", Pay_Extend);
            Biz_Content.put("feeMerId", "");
            Biz_Content.put("subMchId", subMchId);
            Biz_Content.put("notifyUrl", BaoFuConstants.JUHE_PAY_CALLBACK);
            Biz_Content.put("pageUrl", "");
            Biz_Content.put("forbidCredit", "0");//1：禁止,0：不禁止;不传默认为0

            Biz_Content.put("attach", "");
            Biz_Content.put("reqReserved", "");


            //Biz_Content.put("mktInfo", "");

            ///风控参数
            RiskInfoEntity rie = new RiskInfoEntity();
            rie.setLocationPoint("");
            rie.setClientIp("181.219.133.152");
            Biz_Content.put("riskInfo", rie);


            PostMasterEntity pme = new PostMasterEntity();

            String BizContent = JSON.toJSONString(Biz_Content);
            log.info(BizContent);

            String BizContentEn = JHSignatureUtils.encryptByRSA(BizContent, pfxpath, pfxpwd);

            pme.setBizContent(BizContent);
            pme.setSignStr(BizContentEn);
            pme.setMerId(merId);
            pme.setTerId(terId);
            pme.setMethod(Method);

            log.info("请求参数" + pme);

            String PostString = HttpUtil.RequestForm(BaoFuConstants.BAOFU_JUHE_URL, pme);

            log.info("返回参数：" + PostString);
            ResultMasterEntity rme = JSON.parseObject(PostString, ResultMasterEntity.class);

            log.info(rme.toString());

            if (JHSignatureUtils.verifySignature(cerpath, rme.getDataContent(), rme.getSignStr())) {
                log.info("YES");
            } else {
                log.info("NO");
            }
            return rme;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new ServiceException(ex.getMessage());
        }

    }

    public ResultMasterEntity refund(DoorOrder orderInfo) {
        try {
            String pfxpath = "D:\\CER_EN_DECODE\\NTestNewKey\\BAOFU20240612_pri.pfx";//商户私钥
            String cerpath = "D:\\CER_EN_DECODE\\NTestNewKey\\BAOFUP20240612_pub.cer";//宝付公钥
            pfxpath = BaofuUtil.getPath(BaoFuConstants.PFX_PATH);
            cerpath = BaofuUtil.getPath(BaoFuConstants.CER_PATH);
            String pfxpwd = BaoFuConstants.PASS_WORD;//私钥密码
            String merId = BaoFuConstants.MEMBER_ID;
            String terId = BaoFuConstants.TERMINAL_ID;


            String txnTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());//报文发送日期时间
            String Method = "order_refund";

            String originTradeNo = orderInfo.getTradeNo();//原支付订单宝付订单号
            String merchantName = "";//商户名称
            String originOutTradeNo = orderInfo.getOrderNo();//原支付订单商户订单号 [与原支付订单宝付交易号二选一比传]

            String outTradeNo =orderInfo.getRefundNo();// "R" + orderInfo.getOrderNo();
            log.info("退款订单号：" + outTradeNo);

            String notifyUrl = BaoFuConstants.JUHE_REFUND_CALLBACK;//服务端通知地址

            String refundAmt = String.valueOf(orderInfo.getTotalPrice().multiply(BigDecimal.valueOf(100)).intValue());//退款金额
            String totalAmt = String.valueOf(orderInfo.getTotalPrice().multiply(BigDecimal.valueOf(100)).intValue());//订单总金额


            Map<String, Object> Biz_Content = new HashMap<String, Object>();
            Biz_Content.put("agentMerId", "");
            Biz_Content.put("agentTerId", "");
            Biz_Content.put("merId", merId);
            Biz_Content.put("terId", terId);
            Biz_Content.put("originTradeNo", originTradeNo);//原支付订单宝付交易号，推荐传入此值
            Biz_Content.put("originOutTradeNo", originOutTradeNo);//原支付订单商户订单号，与原支付订单宝付交易号二选一比传
            Biz_Content.put("outTradeNo", outTradeNo);//商户系统内部退款订单号，同一个商户号下唯一
            Biz_Content.put("notifyUrl", notifyUrl);
            Biz_Content.put("merchantName", merchantName);
            Biz_Content.put("refundAmt", refundAmt);
            Biz_Content.put("totalAmt", totalAmt);
            Biz_Content.put("txnTime", txnTime);
            Biz_Content.put("attach", "");//预留字段
            Biz_Content.put("reqReserved", "");//请求方保留域


            Biz_Content.put("advanceAmt", "");//垫资金额
            Biz_Content.put("refundReason", "退款");

            PostMasterEntity pme = new PostMasterEntity();
            String BizContent = JSON.toJSONString(Biz_Content);
            ;
            log.info("请求报文：" + BizContent);

            String BizContentEn = JHSignatureUtils.encryptByRSA(BizContent, pfxpath, pfxpwd);

            pme.setBizContent(BizContent);
            pme.setSignStr(BizContentEn);
            pme.setMerId(merId);
            pme.setTerId(terId);
            pme.setMethod(Method);
            log.info("请求参数：" + pme);

            String PostString = HttpUtil.RequestForm(BaoFuConstants.BAOFU_JUHE_URL, pme);

            log.info(PostString);
            ResultMasterEntity rme = JSON.parseObject(PostString, ResultMasterEntity.class);

            log.info(rme.toString());

            if (JHSignatureUtils.verifySignature(cerpath, rme.getDataContent(), rme.getSignStr())) {
                log.info("验签：YES");
            } else {
                log.info("验签：NO");
            }
            easyEntityQuery.updatable(DoorOrder.class)
                    .setColumns(d->d.refundResp().set(rme.toString()))
                    .where(d ->  d.orderNo().eq(orderInfo.getOrderNo()))
                    .executeRows();
            return rme;

        } catch (Exception ex) {
            easyEntityQuery.updatable(DoorOrder.class)
                            .setColumns(d->d.refundResp().set(ExceptionUtil.stacktraceToString(ex.getCause())))
                    .where(d ->  d.orderNo().eq(orderInfo.getOrderNo()))
                    .executeRows();
            ex.printStackTrace();
            throw new ServiceException(ex.getMessage());
        }
    }
}
